/**
 * Copyright 2008-2009 HAN.BIFANG
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package han.bashe.business.adapter;

import han.bashe.business.adapter.http.HttpAdapter;
import han.bashe.business.adapter.jms.JmsAdapter;
import han.bashe.business.adapter.soap.SoapAdapter;
import han.bashe.business.adapter.webservices.WebServicesAdapter;
import han.bashe.business.pipeline.Handler;
import han.bashe.business.pipeline.PipelineContext;
import han.bashe.business.servicequery.CacheWrapper;
import han.bashe.common.config.Config;
import han.bashe.common.entity.BifangEntityConstants;
import han.bashe.common.jms.JmsBinding;
import han.bashe.common.jms.JmsBindingWrapper;
import han.bashe.common.jms.JmsServer;
import han.bashe.common.jms.MqJms;
import han.bashe.common.jms.NormalJms;
import han.bashe.common.message.NormalizedMessage;
import han.bashe.common.message.RequestHelper;
import han.bashe.common.schema.ServiceBusUtil;
import han.bashe.common.util.QosUtil;

import java.util.List;
import java.util.Random;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import v1.message.bashe.han.BasheResponseDocument;
import v1.query.web.bifang.han.ServiceBusDocument.ServiceBus;
import v1.query.web.bifang.han.VersionDocument.Version;

/**
 * @Author Kent
 */
public class AdapterHandler extends Handler {
	private static Log logger = LogFactory.getLog(AdapterHandler.class);
	
	@Override
	public void postProcess(PipelineContext ctx) {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean preProcess(PipelineContext ctx) {
		if (ctx.hasError())
			return false;
		return true;
	}

	@Override
	public void process(PipelineContext ctx) {
		logger.info("AdapterHandler process....");
		try {
			RequestHelper rh = new RequestHelper(ctx.getRequest().copy());
			Version v = ctx.getService().getVersion(rh.getServiceVersion());
			
			NormalizedMessage res = null;
			
			
			
			ServiceBus b = CacheWrapper.getServiceBus(Config
					.getCurrentBusId());
			
			if (ctx.isLocalDomainService()) {
				if (ctx.isBindingToThisBus()) {
					if (ctx.getMethod() != null) {
						String commType = QosUtil.getCommonType(ctx
								.getMethodQos());
						if (commType
								.endsWith(BifangEntityConstants.ASYNC_WITH_REPLY)) {
							

							rh.setBusCode(b.getCode());
							rh.setNotifyService(b.getNotifyServiceCode());
							rh.setNotifyServiceVersion(b
									.getNotifyServiceVersion());

						}
					}
					
					rh.removeLogId();
					rh.removeReplyServiceCode();
					rh.removeReplyServiceVersion();
					rh.removeRetryLogId();
					rh.removeBusCon();

					String bindType = v.getBindingType();
					ctx.setRequestTime(System.currentTimeMillis());
					
					if (bindType.equals(BifangEntityConstants.BINDING_HTTP)) {
						Params p = new Params();
						int timeout = QosUtil.getTimeout(ctx.getService()
								.getVersionQos(rh.getServiceVersion()));
						p.setTimeout(timeout);
						res = HttpAdapter.call(rh.getMessage(), v.getBinding()
								.getHttpBinding(), p);

					} else if (bindType
							.equals(BifangEntityConstants.BINDING_SOAP)) {
						Params p = new Params();
						int timeout = QosUtil.getTimeout(ctx.getService()
								.getVersionQos(rh.getServiceVersion()));
						p.setTimeout(timeout);
						res = SoapAdapter.call(rh.getMessage(), v.getBinding()
								.getSoapBinding(), p);

					} else if (bindType
							.equals(BifangEntityConstants.BINDING_JMS)) {
						JmsBindingWrapper jw = new JmsBindingWrapper();
						JmsBinding jb = new JmsBinding();
						jb.setJmsPassword(v.getBinding().getJmsBinding()
								.getJmsPassword());
						jb.setJmsType(v.getBinding().getJmsBinding()
								.getJmsType());
						jb.setJmsUser(v.getBinding().getJmsBinding()
								.getJmsUser());
						jb
								.setServer(v.getBinding().getJmsBinding()
										.getServer());
						jb.setServerVersion(v.getBinding().getJmsBinding()
								.getServerVersion());
						jw.setJmsBinding(jb);
						if (jb.getServer().equalsIgnoreCase(JmsServer.MQ)) {
							MqJms info = new MqJms();
							info.setCcsid(v.getBinding().getJmsBinding()
									.getInfo().getMqJms().getCcsid());
							info.setMqHost(v.getBinding().getJmsBinding()
									.getInfo().getMqJms().getMqHost());
							info.setQmChannel(v.getBinding().getJmsBinding()
									.getInfo().getMqJms().getQmChannel());
							info.setQmManager(v.getBinding().getJmsBinding()
									.getInfo().getMqJms().getQmManager());
							info.setQmPort(v.getBinding().getJmsBinding()
									.getInfo().getMqJms().getQmPort());
							info.setQueue(v.getBinding().getJmsBinding()
									.getInfo().getMqJms().getQueue());
							jw.setInfo(info);
						} else {
							NormalJms info = new NormalJms();
							info.setDestinationJndi(v.getBinding()
									.getJmsBinding().getInfo().getNormalJms()
									.getDestinationJndi());
							info.setFactoryUrl(v.getBinding().getJmsBinding()
									.getInfo().getNormalJms().getFactoryUrl());
							info.setServerUrl(v.getBinding().getJmsBinding()
									.getInfo().getNormalJms().getServerUrl());
							jw.setInfo(info);
						}

						JmsAdapter.call(rh.getMessage(), jw);
						res = new NormalizedMessage();
						BasheResponseDocument doc = BasheResponseDocument.Factory
								.newInstance();
						doc.addNewBasheResponse().addNewMessageSentOk();
						res.setBody(doc.toString());

					} else if (bindType
							.equals(BifangEntityConstants.BINDING_WEB_SERVICES)) {
						Params p = new Params();
						int timeout = QosUtil.getTimeout(ctx.getMethodQos());
						p.setTimeout(timeout);
						String soapAction = ctx.getMethod().getSoapAction();
						res = WebServicesAdapter.call(rh.getMessage(), v
								.getBinding().getWebServicesBinding(),
								soapAction, p);

					}

				} else {
					rh.setReplyServiceCode(b.getNotifyServiceCode());
					rh.setReplyServiceVersion(b.getNotifyServiceVersion());
					
					String busId = ctx.getService().getService().getBusRelList().get(0);
					ServiceBus target = CacheWrapper.getServiceBus(busId);
					JmsBindingWrapper jw = ServiceBusUtil.getJmsBinding(target);
					
					JmsAdapter.call(rh.getMessage(), jw);
					res = new NormalizedMessage();
					BasheResponseDocument doc = BasheResponseDocument.Factory
							.newInstance();
					doc.addNewBasheResponse().addNewMessageSentOk();
					res.setBody(doc.toString());

				}

			} else {
				
				rh.setReplyServiceCode(b.getNotifyServiceCode());
				rh.setReplyServiceVersion(b.getNotifyServiceVersion());
				
				
				List<String> rel = ctx.getMappingService().getService().getBusRelList();
				byte[] bb = new byte[1];
				 new Random().nextBytes(bb) ;
				int i = ((int)bb[0]) % rel.size();
				String id = rel.get(i);
				
				ServiceBus target = CacheWrapper.getServiceBus(id);
				
				JmsBindingWrapper jw = ServiceBusUtil.getJmsBinding(target);
				
				JmsAdapter.call(rh.getMessage(), jw);
				res = new NormalizedMessage(); 
				BasheResponseDocument doc = BasheResponseDocument.Factory
						.newInstance();
				doc.addNewBasheResponse().addNewMessageSentOk();
				res.setBody(doc.toString());
				
			}
			ctx.setResponseTime(System.currentTimeMillis());
			ctx.setResponset(res);
		} catch (Exception e) {
			logger
					.error(
							"AdapterHandler.process() error :",
							e);
			ctx.setError(e);
		}

	}
}
